{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-06-03 19:38:41.857297: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
      "2024-06-03 19:38:41.857523: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n",
      "2024-06-03 19:38:41.859701: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n",
      "2024-06-03 19:38:41.896047: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
      "To enable the following instructions: AVX2 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
      "2024-06-03 19:38:42.375847: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "mnist = tf.keras.datasets.mnist\n",
    "\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "# 将图像数据归一化。原始图像像素值在0到255之间，通过将像素值除以255.0，所有像素值将被缩放到0到1之间。\n",
    "# 这有助于加快模型训练过程并提高训练效果\n",
    "x_train, x_test = x_train / 255.0, x_test / 255.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/azhao/projects/demo/pytf-demo/.tf2/lib/python3.12/site-packages/keras/src/layers/reshaping/flatten.py:37: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n",
      "  super().__init__(**kwargs)\n"
     ]
    }
   ],
   "source": [
    "# Sequential 模型是多个网络层的线性堆叠。通过将各层按顺序添加到模型中来构建网络。\n",
    "# Flatten层将输入数据从二维(28x28像素)展平为一维(784个像素)。这一步将28x28的二维数组转换为一维数组以便于输入到后续的全连接层。\n",
    "# Dense层是一个全连接层，包含128个神经元。activation='relu'表示使用ReLU激活函数。\n",
    "# 这个Dense(10)层是输出层，包含10个神经元，对应于0到9的10个类别。这个层没有指定激活函数，因为在分类任务中，最后一层通常会在损失函数中应用softmax激活。\n",
    "model = tf.keras.models.Sequential([\n",
    "  tf.keras.layers.Flatten(input_shape=(28, 28)),\n",
    "  tf.keras.layers.Dense(128, activation='relu'),\n",
    "  tf.keras.layers.Dropout(0.2),\n",
    "  tf.keras.layers.Dense(10)\n",
    "])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个有什么影响？\n",
    "\n",
    "/home/azhao/projects/demo/pytf-demo/.tf2/lib/python3.12/site-packages/keras/src/layers/reshaping/flatten.py:37: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n",
    "  super().__init__(**kwargs)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.1547753 , -0.70141304,  0.11036113,  0.00986226, -0.13460317,\n",
       "        -0.6278589 ,  0.31592607,  0.6216268 , -0.92430073,  0.66679513]],\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predictions = model(x_train[:1]).numpy()\n",
    "predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.0317552 , 0.04996979, 0.11252695, 0.10176782, 0.08807851,\n",
       "        0.05378383, 0.13820772, 0.18762748, 0.03998606, 0.19629662]],\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.nn.softmax(predictions).numpy()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 稀疏分类交叉熵\n",
    "loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0503714"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "loss_fn(y_train[:1], predictions).numpy()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer='adam',\n",
    "              loss=loss_fn,\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/5\n",
      "\u001b[1m1875/1875\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 1ms/step - accuracy: 0.8638 - loss: 0.4740\n",
      "Epoch 2/5\n",
      "\u001b[1m1875/1875\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 1ms/step - accuracy: 0.9571 - loss: 0.1480\n",
      "Epoch 3/5\n",
      "\u001b[1m1875/1875\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 1ms/step - accuracy: 0.9661 - loss: 0.1110\n",
      "Epoch 4/5\n",
      "\u001b[1m1875/1875\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 1ms/step - accuracy: 0.9731 - loss: 0.0867\n",
      "Epoch 5/5\n",
      "\u001b[1m1875/1875\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 1ms/step - accuracy: 0.9776 - loss: 0.0736\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.src.callbacks.history.History at 0x7fbd954b61e0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(x_train, y_train, epochs=5)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "313/313 - 0s - 663us/step - accuracy: 0.9781 - loss: 0.0736\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.07364669442176819, 0.9781000018119812]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(x_test,  y_test, verbose=2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "probability_model = tf.keras.Sequential([\n",
    "  model,\n",
    "  tf.keras.layers.Softmax()\n",
    "])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(5, 10), dtype=float32, numpy=\n",
       "array([[8.2485325e-09, 3.2875707e-07, 1.8318208e-06, 4.4108272e-04,\n",
       "        3.9674736e-11, 1.0097248e-06, 1.5005348e-12, 9.9954921e-01,\n",
       "        4.3028376e-07, 6.0262473e-06],\n",
       "       [9.6423534e-08, 2.0142770e-05, 9.9997592e-01, 6.7702821e-08,\n",
       "        4.8312120e-14, 3.7625506e-07, 1.7880008e-06, 1.6420365e-13,\n",
       "        1.5219945e-06, 4.0893970e-13],\n",
       "       [2.2061479e-07, 9.9852610e-01, 4.6275960e-05, 7.3924548e-06,\n",
       "        8.2543353e-05, 1.3419872e-06, 3.7632672e-05, 1.0887447e-03,\n",
       "        2.0808348e-04, 1.6154144e-06],\n",
       "       [9.9993074e-01, 4.6494879e-09, 1.5466726e-06, 2.8315884e-07,\n",
       "        6.3143858e-07, 2.7665189e-06, 4.6137022e-05, 1.6628630e-05,\n",
       "        2.2847406e-09, 1.2512014e-06],\n",
       "       [6.5166620e-05, 2.5547251e-09, 3.8900784e-05, 1.7842707e-06,\n",
       "        9.9749964e-01, 1.9876145e-06, 8.5884885e-06, 8.2280213e-04,\n",
       "        1.6585060e-06, 1.5594369e-03]], dtype=float32)>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "probability_model(x_test[:5])\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".tf2",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
